/**
**************************************************************************************
*Founder Effect                                                                      *
*Copyright (C) 2006-2007, 5d Studios (www.5d-Studios.com)                            *
*                                                                                    *
*This library is free software; you can redistribute it and/or                       *
*modify it under the terms of the GNU Lesser General Public                          *
*License as published by the Free Software Foundation; either                        *
*version 2.1 of the License, or (at your option) any later version.                  *
*                                                                                    *
*This library is distributed in the hope that it will be useful,                     *
*but WITHOUT ANY WARRANTY; without even the implied warranty of                      *
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU                   *
*Lesser General Public License for more details.                                     *
*                                                                                    *
*You should have received a copy of the GNU Lesser General Public                    *
*License along with this library; if not, write to the Free Software                 *
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA      *
**************************************************************************************
*/
#include "StdAfx.h"
#include "Timer.h"


Timer::Timer(void)
{
    m_frames     = 0.0f;
	m_frametime  = 0.0f;
	m_time      = 0.0f;
	m_pauseTime = 0.0f;
	m_paused  = false;

	if (!QueryPerformanceFrequency((LARGE_INTEGER *) &m_frequency))
	{
		// no performance counter available, you might be using w98 osr1
		m_resolution = 0.001f;
		m_performanceTimerEnabled = 0;
		//exit(-1);	// I usually exit in this situation
	}
	else
	{ 
		// performance counter is available, use it instead of multimedia timer
		m_performanceTimerEnabled = 1;

		// get 32 out of the 64 time bits such that we have around 1 microsecond resolution
		unsigned int lowpart = (unsigned int)m_frequency.LowPart;
		unsigned int highpart = (unsigned int)m_frequency.HighPart;
		m_lowshift = 0;

		while (highpart || (lowpart > 2000000.0))
		{
			m_lowshift++;
			lowpart >>= 1;
			lowpart |= (highpart & 1) << 31;
			highpart >>= 1;
		}
		m_resolution = 1.0 / (double)lowpart;
	}
}


int Timer::Refresh()
{
	LARGE_INTEGER	count;
	unsigned int	temp, t2;

	if(m_performanceTimerEnabled)
	{
		QueryPerformanceCounter((LARGE_INTEGER *) &count);

		temp = ((unsigned int)count.LowPart  >> m_lowshift) |
			   ((unsigned int)count.HighPart << (32 - m_lowshift));


		// check for firstframe, turnover or backward time
		if (m_frames==0 || ((temp <= m_oldTime) && ((m_oldTime - temp) < 0x10000000)))
		{
			m_oldTime = temp;
		}
		else 
		{
			t2 = temp - m_oldTime;
			m_frametime = (double)t2 * m_resolution; //*0.5; // Slows down everything
			if(m_frametime > 0.05)	// Max frametime of 0.05 seconds
				m_frametime = 0.05;
			m_time += m_frametime;

			m_oldTime = temp;

			if (m_time == m_lastTime)
			{
				m_sametimecount++;

				if (m_sametimecount > 100000)
				{
					m_time += 1.0;
					m_sametimecount = 0;
				}
			}
			else m_sametimecount = 0;

			m_lastTime = m_time;
		}
		m_frames++;
	}
	else	// No perfomance counter
	{
		if(m_frames == 0)
		{
			m_lastTime = m_time = /*SDL_GetTicks() **/ m_resolution;
			m_frametime = 0;
		}
		else
		{
			m_lastTime = m_time;
			m_time = /*SDL_GetTicks() **/ m_resolution;
			m_frametime = m_time - m_lastTime;
			if(m_frametime > 0.05)
			{
				m_time -= (m_frametime - 0.05);
				m_frametime = 0.05;
			}
		}
	}
	m_frames++;
	return m_frames;
}


void Timer::Pause()
{
	if(!m_paused)
	{
		m_pauseTime = m_time;
		m_paused = true;
	}

}

void Timer::UnPause()
{
	if(m_paused)
	{
		m_time = m_pauseTime;
		m_paused = false;
	}
}


Timer::~Timer(void)
{
}
